home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / cvs / dist / src / modules.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-02-06  |  8.1 KB  |  324 lines

  1. #ifndef lint
  2. static char rcsid[] = "$Id: modules.c,v 1.14.1.1 91/01/29 07:17:32 berliner Exp $";
  3. #endif !lint
  4.  
  5. /*
  6.  *    Copyright (c) 1989, Brian Berliner
  7.  *
  8.  *    You may distribute under the terms of the GNU General Public License
  9.  *    as specified in the README file that comes with the CVS 1.0 kit.
  10.  *
  11.  * Modules
  12.  *
  13.  *    Functions for accessing the modules file.
  14.  *
  15.  *    The modules file supports basically three formats of lines:
  16.  *        key [options] directory files...
  17.  *        key [options] directory
  18.  *        key -a aliases...
  19.  *
  20.  *    The -a option allows an aliasing step in the parsing of the modules
  21.  *    file.  The "aliases" listed on a line following the -a are
  22.  *    processed one-by-one, as if they were specified as arguments on the
  23.  *    command line.
  24.  */
  25.  
  26. #include <sys/param.h>
  27. #include <sys/file.h>
  28. #include <ndbm.h>
  29. #include "cvs.h"
  30.  
  31. extern int update_build_dirs;
  32.  
  33. int run_module_prog = 1;        /* run -i/-o/-t prog by default */
  34.  
  35. /*
  36.  * Open the modules file, and die if the CVSROOT environment variable
  37.  * was not set.  If the modules file does not exist, that's fine, and
  38.  * a warning message is displayed and a NULL is returned.
  39.  */
  40. DBM *
  41. open_module()
  42. {
  43.     char mfile[MAXPATHLEN];
  44.     DBM *db;
  45.  
  46.     if (CVSroot == NULL) {
  47.     (void) fprintf(stderr, "%s: must set the CVSROOT environment variable\n",
  48.                progname);
  49.     error(0, "or specify the '-d' option to %s", progname);
  50.     }
  51.     (void) sprintf(mfile, "%s/%s", CVSroot, CVSROOTADM_MODULES);
  52.     if ((db = dbm_open(mfile, O_RDONLY, 0666)) == NULL)
  53.     warn(0, "warning: cannot open modules file %s", mfile);
  54.     return (db);
  55. }
  56.  
  57. /*
  58.  * Close the modules file, if the open succeeded, that is
  59.  */
  60. close_module(db)
  61.     DBM *db;
  62. {
  63.     if (db != NULL) {
  64.     dbm_close(db);
  65.     }
  66. }
  67.  
  68. /*
  69.  * This is the recursive function that processes a module name.
  70.  * If tag is set, just tag files, otherwise, we were called to check files
  71.  * out.
  72.  */
  73. do_module(db, mname, m_type, msg)
  74.     DBM *db;
  75.     char *mname;
  76.     enum mtype m_type;
  77.     char *msg;
  78. {
  79.     char *checkin_prog = NULL, *checkout_prog = NULL, *tag_prog = NULL;
  80.     char cwd[MAXPATHLEN], file[MAXPATHLEN];
  81.     char *moduleargv[MAXFILEPERDIR];
  82.     int moduleargc, just_file;
  83.     datum key, val;
  84.     char *cp, **argv;
  85.     int c, alias = 0, argc, err = 0;
  86.  
  87.     just_file = FALSE;
  88.     update_build_dirs = FALSE;
  89.     /*
  90.      * Look the argument module name up in the database; if we found it, use
  91.      * it, otherwise, see if the file or directory exists relative to the
  92.      * root directory (CVSroot).  If there is a directory there, it is
  93.      * extracted or tagged recursively; if there is a file there, it is
  94.      * extracted or tagged individually; if there is no file or directory
  95.      * there, we are done.
  96.      */
  97.     key.dptr = mname;
  98.     key.dsize = strlen(key.dptr);
  99.     if (db != NULL)
  100.     val = dbm_fetch(db, key);
  101.     else
  102.     val.dptr = NULL;
  103.     if (val.dptr != NULL) {
  104.     val.dptr[val.dsize] = '\0';
  105.     } else {
  106.     /*
  107.      * Need to determine if the argument module name is a directory
  108.      * or a file relative to the CVS root and set update_build_dirs
  109.      * and just_file accordingly
  110.      */
  111.     update_build_dirs = TRUE;
  112.     (void) sprintf(file, "%s/%s", CVSroot, key.dptr);
  113.     if (!isdir(file)) {
  114.         (void) strcat(file, RCSEXT);
  115.         if (!isfile(file)) {
  116.         warn(0, "cannot find '%s' - ignored", key.dptr);
  117.         err++;
  118.         return (err);
  119.         } else {
  120.         update_build_dirs = FALSE;
  121.         just_file = TRUE;
  122.         }
  123.     }
  124.     val = key;
  125.     }
  126.     /*
  127.      * If just extracting or tagging files, need to munge the
  128.      * passed in module name to look like an actual module entry.
  129.      */
  130.     if (just_file == TRUE) {
  131.     if ((cp = rindex(key.dptr, '/')) != NULL) {
  132.         *cp++ = '\0';
  133.     } else {
  134.         cp = key.dptr;
  135.         key.dptr = ".";
  136.     }
  137.     (void) sprintf(file, "%s %s %s", key.dptr, key.dptr, cp);
  138.     } else {
  139.     (void) sprintf(file, "%s %s", key.dptr, val.dptr);
  140.     }
  141.     line2argv(&moduleargc, moduleargv, file);
  142.     argc = moduleargc;
  143.     argv = moduleargv;
  144.     if (getwd(cwd) == NULL)
  145.     error(0, "cannot get current working directory: %s", cwd);
  146.     optind = 1;
  147.     while ((c = getopt(argc, argv, CVSMODULE_OPTS)) != -1) {
  148.     switch (c) {
  149.     case 'a':
  150.         alias = 1;
  151.         break;
  152.     case 'i':
  153.         checkin_prog = optarg;
  154.         break;
  155.     case 'o':
  156.         checkout_prog = optarg;
  157.         break;
  158.     case 't':
  159.         tag_prog = optarg;
  160.         break;
  161.     case '?':
  162.         warn(0, "modules file has invalid option for key %s value %s",
  163.          key.dptr, val.dptr);
  164.         err++;
  165.         return (err);
  166.         break;
  167.     }
  168.     }
  169.     argc -= optind;
  170.     argv += optind;
  171.     if (argc == 0) {
  172.     warn(0, "modules file missing directory for key %s value %s",
  173.          key.dptr, val.dptr);
  174.     err++;
  175.     return (err);
  176.     }
  177.     if (alias) {
  178.     register int i;
  179.  
  180.     for (i = 0; i < argc; i++) {
  181.         if (!quiet)
  182.         printf("%s %s: %s %s\n", progname, command, msg, argv[i]);
  183.         err += do_module(db, argv[i], m_type, msg);
  184.     }
  185.     return (err);
  186.     }
  187.     err += process_module(argc, argv, m_type, &key);
  188.     if (err == 0 && run_module_prog) {
  189.     if (m_type == CHECKOUT && checkin_prog !=  NULL) {
  190.         FILE *fp = open_file(CVSADM_CIPROG, "w+");
  191.         (void) fprintf(fp, "%s\n", checkin_prog);
  192.         (void) fclose(fp);
  193.     }
  194.     }
  195.     if (chdir(cwd) < 0)
  196.     error(1, "failed chdir to %s!", cwd);
  197.     if (err == 0 && run_module_prog) {
  198.     if ((m_type == TAG && tag_prog != NULL) ||
  199.         (m_type == CHECKOUT && checkout_prog != NULL)) {
  200.         (void) sprintf(prog, "%s %s",
  201.                m_type == TAG ? tag_prog : checkout_prog, key.dptr);
  202.         if (!quiet)
  203.         printf("%s %s: Executing '%s'\n", progname, command, prog);
  204.         err += system(prog);
  205.     }
  206.     }
  207.     free_names(&moduleargc, moduleargv);
  208.     return (err);
  209. }
  210.  
  211. static
  212. process_module(argc, argv, m_type, keyp)
  213.     int argc;
  214.     char *argv[];
  215.     enum mtype m_type;
  216.     datum *keyp;
  217. {
  218.     register int i, just_file;
  219.     int err = 0;
  220.  
  221.     just_file = argc > 1;
  222.     if (!just_file && update_build_dirs == FALSE && argc == 1)
  223.     update_build_dirs = TRUE;
  224.     if (m_type == TAG || m_type == PATCH) {
  225.     (void) sprintf(Repository, "%s/%s", CVSroot, argv[0]);
  226.     if (chdir(Repository) < 0) {
  227.         warn(1, "cannot chdir to %s", Repository);
  228.         err++;
  229.         return (err);
  230.     }
  231.     } else {
  232.     if (Build_Dirs_and_chdir(keyp->dptr) != 0) {
  233.         warn(0, "ignoring module %s", keyp->dptr);
  234.         err++;
  235.         return (err);
  236.     }
  237.     (void) sprintf(Repository, "%s/%s", CVSroot, argv[0]);
  238.     if (!isdir(CVSADM)) {
  239.         FILE *fp;
  240.  
  241.         Create_Admin(Repository, DFLT_RECORD);
  242.         if (just_file == TRUE) {
  243.         fp = open_file(CVSADM_ENTSTAT, "w+");
  244.         (void) fclose(fp);
  245.         }
  246.     } else {
  247.         char file[MAXPATHLEN];
  248.  
  249.         (void) strcpy(file, Repository);
  250.         Name_Repository();
  251.         if (strcmp(Repository, file) != 0) {
  252.         warn(0, "existing repository %s does not match %s",
  253.              Repository, file);
  254.         err++;
  255.         return (err);
  256.         }
  257.     }
  258.     }
  259.     if (update_build_dirs == TRUE) {
  260.     extern char update_dir[];
  261.  
  262.     (void) strcpy(update_dir, keyp->dptr);
  263.     if (m_type == CHECKOUT)
  264.         err += update(0, (char **)0);
  265.     else if (m_type == TAG)
  266.         err += tagit((char *)0);
  267.     else if (m_type == PATCH)
  268.         err += patched((char *)0);
  269.     else
  270.         error(0, "impossible module type %d", (int)m_type);
  271.     update_dir[0] = '\0';
  272.     return (err);
  273.     }
  274.     argc--;
  275.     argv++;
  276.     for (i = 0; i < argc; i++) {
  277.     char line[MAXLINELEN];
  278.  
  279.     (void) strcpy(User, argv[i]);
  280.     (void) sprintf(Rcs, "%s/%s%s", Repository, User, RCSEXT);
  281.     if (m_type == CHECKOUT) {
  282.         Version_TS(Rcs, Tag, User);
  283.         if (TS_User[0] == '\0') {
  284.         (void) sprintf(line, "Initial %s", User);
  285.         Register(User, VN_Rcs, line);
  286.         }
  287.     } else if (m_type == TAG) {
  288.         err += tagit(Rcs);
  289.     } else if (m_type == PATCH) {
  290.         err += patched(Rcs);
  291.     } else {
  292.         error(0, "impossible module type %d", (int)m_type);
  293.     }
  294.     }
  295.     if (m_type == CHECKOUT)
  296.     err += update(++argc, --argv);
  297.     return (err);
  298. }
  299.  
  300. cat_module()
  301. {
  302.     FILE *fp;
  303.     DBM *db;
  304.     datum key, val;
  305.  
  306.     if ((db = open_module()) == NULL)
  307.     error(0, "failed to cat the modules file");
  308.     if ((fp = popen(SORT, "w")) == NULL)
  309.     fp = stdout;
  310.     for (key = dbm_firstkey(db); key.dptr != NULL; key = dbm_nextkey(db)) {
  311.     key.dptr[key.dsize] = '\0';
  312.     (void) fprintf(fp, "%-20s", key.dptr);
  313.     val = dbm_fetch(db, key);
  314.     if (val.dptr != NULL) {
  315.         val.dptr[val.dsize] = '\0';
  316.         (void) fprintf(fp, " %s\n", val.dptr);
  317.     } else {
  318.         (void) fprintf(fp, "\n");
  319.     }
  320.     }
  321.     if (fp != stdout)
  322.     (void) pclose(fp);
  323. }
  324.